<template>
  <div class="action-auth-control">
    <div class="top">
      <div class="control">全选</div>
      <div class="box">
        <span class="text">可见</span>
        <a-checkbox
          v-model:checked="visibleCheckAll"
          :indeterminate="visibleIndeterminate"
          @change="(ev) => onCheckAllChange(ev, 'visible')"
        />
      </div>
      <div class="box">
        <span class="text">可写</span>
        <a-checkbox
          v-model:checked="writeCheckAll"
          :indeterminate="writeIndeterminate"
          @change="(ev) => onCheckAllChange(ev, 'write')"
        />
      </div>
      <div class="box">
        <span class="text">必填</span>
        <a-checkbox
          v-model:checked="requiredCheckAll"
          :indeterminate="requiredIndeterminate"
          @change="(ev) => onCheckAllChange(ev, 'required')"
        />
      </div>
    </div>
    <div class="list">
      <div class="item" v-for="item in formCards" :key="item.cardCode">
        <div class="control">{{ item.controls.displayName.defaultValue }}</div>
        <template v-if="val[item.cardCode]">
          <div class="box">
            <a-checkbox v-model:checked="val[item.cardCode].visible" />
          </div>
          <div class="box">
            <a-checkbox v-model:checked="val[item.cardCode].write" />
          </div>
          <div class="box">
            <a-checkbox v-model:checked="val[item.cardCode].required" />
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed, reactive, watch, toRefs } from 'vue';

export default defineComponent({
  name: 'ActionAuthControl',
  props: {
    value: {
      type: Object,
      default: () => ({}),
    },
    controls: {
      type: Object,
      default: () => ({}),
    },
    controlKey: {
      type: String,
      default: () => '',
    },
    formCards: {
      type: Array as any,
      default: () => [],
    },
  },
  setup(prop, context) {
    const val: any = computed({
      get: () => {
        if (Object.keys(prop.value).length) return prop.value;
        const obj = {};
        prop.formCards.forEach((el: any) => {
          Object.assign(obj, {
            [el.cardCode]: { visible: true, write: false, required: false },
          });
        });
        return obj;
      },
      set: (val) => {
        context.emit('updateValue', val, prop.controlKey, prop.controls);
      },
    });
    const state: any = reactive({
      visibleIndeterminate: false,
      visibleCheckAll: true,
      writeIndeterminate: false,
      writeCheckAll: false,
      requiredIndeterminate: false,
      requiredCheckAll: false,
    });
    watch(
      () => val.value,
      (val: any) => {
        ['visible', 'write', 'required'].forEach((type) => {
          const list = Object.keys(val).map((key) => {
            return {
              visible: val[key].visible,
              write: val[key].write,
              required: val[key].required,
            };
          });
          state[`${type}CheckAll`] = list.every((it: any) => it[type]);
          state[`${type}Indeterminate`] =
            list.some((it: any) => it[type]) && !state[`${type}CheckAll`];
        });

        context.emit('updateValue', val, prop.controlKey, prop.controls);
      },
      {
        deep: true,
        immediate: true,
      },
    );
    const onCheckAllChange = (e: any, type: string) => {
      Object.keys(val.value).map((key) => {
        val.value[key][type] = e.target.checked;
      });
      Object.assign(state, {
        [`${type}Indeterminate`]: false,
        [`${type}CheckAll`]: e.target.checked,
      });
    };

    return {
      val,
      ...toRefs(state),
      onCheckAllChange,
    };
  },
});
</script>

<style lang="less" scoped>
.action-auth-control {
  // width: 100%;
  .control {
    flex: 1;
  }
  .box {
    flex: 0 0 auto;
    width: 40px;
  }
  .top {
    .flexRow(space-between, flex-end);
    padding-bottom: 4px;
    border-bottom: 1px solid @rb-border-color-base;
    .box {
      .flexColumn(space-between, flex-start);
    }
  }
  .list {
    padding-top: 4px;
    .item {
      .flexRow();
      line-height: 32px;
    }
  }
}
</style>
